package com.friend.street.util;

import com.sun.imageio.plugins.bmp.BMPImageReader;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.jpeg.JPEGImageReader;
import com.sun.imageio.plugins.png.PNGImageReader;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.MemoryCacheImageInputStream;
import java.awt.*;
import java.awt.image.AreaAveragingScaleFilter;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.io.*;
import java.util.Iterator;

/** 图片的工具类 **/
public class ImageUtil {

    private static Component component = new Canvas();

    /**
     * 将图片缩放成指定大小
     * @param input
     * @param output
     * @param width
     * @param height
     * @throws Exception
     */
    public static void zoom(InputStream input, OutputStream output, int width, int height) throws Exception{
        int length = input.available();
        byte[] bytes = new byte[length];
        input.read(bytes, 0, length);
        input.close();
        zoom(bytes, output, width, height);
    }

    /**
     * 等比缩放图片
     *
     * @param bytes
     * @param output
     * @param width
     * @param height
     * @throws Exception
     */
    private static void zoom(byte[] bytes, OutputStream output, int width, int height) throws Exception {
        String imageType = getImageType(bytes);
        if (!imageType.equals("")) {
            InputStream isImage = new ByteArrayInputStream(bytes);
            BufferedImage image = ImageIO.read(isImage);
            // 原始大小
            int oldWidth = image.getWidth();
            int oldHeight = image.getHeight();
            if (height > 0 && oldWidth / oldHeight > width / height) {
                height = (int) ((double) oldHeight / oldWidth * width);
            } else {
                width = (int) ((double) oldWidth / oldHeight * height);
            }
            AreaAveragingScaleFilter areaAveragingScaleFilter = new AreaAveragingScaleFilter(width, height);
            FilteredImageSource filteredImageSource = new FilteredImageSource(image.getSource(),  areaAveragingScaleFilter);
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
            Graphics graphics = bufferedImage.createGraphics();
            graphics.drawImage(component.createImage(filteredImageSource), 0, 0, null);
            ImageIO.write(bufferedImage, imageType, output);
        } else {
            throw new Exception("Can't zoom this image.");
        }
    }

    /**
     * 转载图片的字节流，解析图片的格式
     * @param imageBytes
     * @return
     * @throws IOException
     */
    private static String getImageType(byte[] imageBytes) throws IOException {
        String type = "";
        ByteArrayInputStream bais = null;
        MemoryCacheImageInputStream mcis = null;
        try {
            bais = new ByteArrayInputStream(imageBytes);
            mcis = new MemoryCacheImageInputStream(bais);
            Iterator<ImageReader> itr = ImageIO.getImageReaders(mcis);
            while (itr.hasNext()) {
                ImageReader reader = (ImageReader) itr.next();
                if (reader instanceof GIFImageReader) {
                    type = "gif";
                } else if (reader instanceof JPEGImageReader) {
                    type = "jpeg";
                } else if (reader instanceof PNGImageReader) {
                    type = "png";
                } else if (reader instanceof BMPImageReader) {
                    type = "bmp";
                }
            }
        } finally {
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException ioe) {
                    bais = null;
                }
            }
            if (mcis != null) {
                try {
                    mcis.close();
                } catch (IOException ioe) {
                    mcis = null;
                }
            }
        }
        return type;
    }


}
